#!/usr/bin/env node

import { writeFile, readFile } from 'fs/promises';
import { PPTXExporter } from '../dist/index.js';

// 进度追踪函数
function createProgressTracker(testName) {
  return progress => {
    const { current, total, percentage, completed } = progress;

    // 创建进度条
    const barLength = 25;
    const filledLength = Math.round((percentage / 100) * barLength);
    const bar = '█'.repeat(filledLength) + '░'.repeat(barLength - filledLength);

    // 清除当前行并输出新的进度信息
    process.stdout.clearLine(0);
    process.stdout.cursorTo(0);
    process.stdout.write(
      `[${bar}] ${percentage}% | ${testName} | ${current}/${total} 张幻灯片`
    );

    if (completed) {
      console.log(' | ✅ 完成'); // 完成时换行
    }
  };
}

// 基础测试数据
const basicTestData = {
  title: 'PPTX Exporter 基础测试',
  width: 960,
  height: 540,
  theme: {
    backgroundColor: '#ffffff',
    themeColors: ['#5b9bd5', '#70ad47', '#ffc000', '#c55a5a'],
    fontColor: '#000000',
    fontName: 'Microsoft YaHei',
    outline: { color: '#000000', width: 1, style: 'solid' },
    shadow: { h: 2, v: 2, blur: 4, color: '#000000' },
  },
  slides: [
    {
      id: 'slide-1',
      elements: [
        {
          type: 'text',
          left: 100,
          top: 100,
          width: 300,
          height: 50,
          content: 'Hello PPTX Exporter!',
          defaultFontName: 'Arial',
          defaultColor: '#000000',
        },
        {
          type: 'text',
          left: 100,
          top: 200,
          width: 400,
          height: 30,
          content: '这是一个基础测试演示文稿',
          defaultFontName: 'Microsoft YaHei',
          defaultColor: '#666666',
        },
        {
          type: 'text',
          left: 100,
          top: 250,
          width: 500,
          height: 100,
          content:
            '<p>支持 <strong>HTML</strong> 格式的文本</p><ul><li>列表项 1</li><li>列表项 2</li></ul>',
          defaultFontName: 'Microsoft YaHei',
          defaultColor: '#333333',
        },
      ],
    },
    {
      id: 'slide-2',
      elements: [
        {
          type: 'shape',
          left: 100,
          top: 100,
          width: 200,
          height: 150,
          path: 'M 0 0 L 200 0 L 200 150 L 0 150 Z',
          viewBox: [200, 150],
          fill: '#ff0000',
          outline: {
            color: '#000000',
            width: 2,
            style: 'solid',
          },
        },
        {
          type: 'line',
          left: 350,
          top: 100,
          width: 2,
          color: '#0000ff',
          style: 'solid',
          points: ['', ''],
          start: [0, 0],
          end: [200, 100],
        },
      ],
    },
  ],
};

// 空演示文稿测试数据
const emptyTestData = {
  title: '空演示文稿测试',
  width: 960,
  height: 540,
  theme: {
    backgroundColor: '#ffffff',
    themeColors: ['#5b9bd5', '#70ad47', '#ffc000', '#c55a5a'],
    fontColor: '#000000',
    fontName: 'Microsoft YaHei',
  },
  slides: [],
};

async function loadTemplateData() {
  try {
    const templateContent = await readFile(
      './test/input/template.json',
      'utf-8'
    );
    return JSON.parse(templateContent);
  } catch (error) {
    console.warn('⚠️ 无法加载模板数据:', error.message);
    return null;
  }
}

async function testEnvironmentDetection() {
  console.log('🔍 测试环境检测...');

  const exporter = new PPTXExporter(basicTestData, {
    onProgress: createProgressTracker('环境检测'),
  });

  console.log('当前环境:', exporter.getEnvironment());
  console.log('支持的格式:', exporter.getSupportedFormats());

  return exporter;
}

async function testBasicExport(exporter, testName, data) {
  console.log(`\n📁 测试 ${testName}...`);

  try {
    // 创建带进度追踪的新导出器实例
    const progressExporter = new PPTXExporter(data, {
      onProgress: createProgressTracker(testName),
    });

    const buffer = await progressExporter.toBuffer();
    const outputPath = `./test/output/${testName}.pptx`;
    await writeFile(outputPath, buffer);

    console.log(`✅ ${testName} 导出成功`);
    console.log(`📊 文件大小: ${(buffer.length / 1024 / 1024).toFixed(2)} MB`);
    console.log(`📄 保存路径: ${outputPath}`);

    return buffer;
  } catch (error) {
    console.error(`❌ ${testName} 导出失败:`, error.message);
    return null;
  }
}

async function testAllExportFormats(exporter, testName) {
  console.log(`\n🔄 测试 ${testName} 的所有导出格式...`);

  const results = {};

  // 创建带进度追踪的导出器
  const progressExporter = new PPTXExporter(exporter.pptData, {
    onProgress: createProgressTracker(`${testName}-Buffer`),
  });

  // 测试 Buffer
  try {
    results.buffer = await progressExporter.toBuffer();
    console.log('✅ Buffer 导出成功');
  } catch (error) {
    console.error('❌ Buffer 导出失败:', error.message);
  }

  // 测试 Base64
  try {
    const base64Exporter = new PPTXExporter(exporter.pptData, {
      onProgress: createProgressTracker(`${testName}-Base64`),
    });
    results.base64 = await base64Exporter.toBase64(true);
    console.log('✅ Base64 导出成功 (带压缩)');
  } catch (error) {
    console.error('❌ Base64 导出失败:', error.message);
  }

  // 测试 ArrayBuffer
  try {
    const arrayBufferExporter = new PPTXExporter(exporter.pptData, {
      onProgress: createProgressTracker(`${testName}-ArrayBuffer`),
    });
    results.arrayBuffer = await arrayBufferExporter.toArrayBuffer(true);
    console.log('✅ ArrayBuffer 导出成功 (带压缩)');
  } catch (error) {
    console.error('❌ ArrayBuffer 导出失败:', error.message);
  }

  // 测试 Uint8Array
  try {
    const uint8ArrayExporter = new PPTXExporter(exporter.pptData, {
      onProgress: createProgressTracker(`${testName}-Uint8Array`),
    });
    results.uint8Array = await uint8ArrayExporter.toUint8Array(true);
    console.log('✅ Uint8Array 导出成功 (带压缩)');
  } catch (error) {
    console.error('❌ Uint8Array 导出失败:', error.message);
  }

  // 测试 BinaryString
  try {
    const binaryStringExporter = new PPTXExporter(exporter.pptData, {
      onProgress: createProgressTracker(`${testName}-BinaryString`),
    });
    results.binaryString = await binaryStringExporter.toBinaryString(true);
    console.log('✅ BinaryString 导出成功 (带压缩)');
  } catch (error) {
    console.error('❌ BinaryString 导出失败:', error.message);
  }

  // 测试 Stream
  try {
    const streamExporter = new PPTXExporter(exporter.pptData, {
      onProgress: createProgressTracker(`${testName}-Stream`),
    });
    results.stream = await streamExporter.toStream();
    console.log('✅ Stream 导出成功');
  } catch (error) {
    console.error('❌ Stream 导出失败:', error.message);
  }

  // 测试智能导出
  try {
    const smartExporter = new PPTXExporter(exporter.pptData, {
      onProgress: createProgressTracker(`${testName}-Smart`),
    });
    results.smart = await smartExporter.smartExport(true);
    console.log('✅ 智能导出成功 (带压缩)');
  } catch (error) {
    console.error('❌ 智能导出失败:', error.message);
  }

  // 测试通用导出
  try {
    const genericExporter = new PPTXExporter(exporter.pptData, {
      onProgress: createProgressTracker(`${testName}-Generic`),
    });
    results.generic = await genericExporter.export({
      outputType: 'base64',
      compression: true,
    });
    console.log('✅ 通用导出成功');
  } catch (error) {
    console.error('❌ 通用导出失败:', error.message);
  }

  return results;
}

async function testFileExport(exporter, testName) {
  console.log(`\n💾 测试 ${testName} 文件导出...`);

  try {
    const fileExporter = new PPTXExporter(exporter.pptData, {
      onProgress: createProgressTracker(`${testName}-File`),
    });
    await fileExporter.toFile(`./test/output/${testName}-file.pptx`, true);
    console.log(`✅ ${testName} 文件导出成功 (带压缩)`);
  } catch (error) {
    console.error(`❌ ${testName} 文件导出失败:`, error.message);
  }
}

async function testErrorHandling() {
  console.log('\n⚠️ 测试错误处理...');

  // 测试无效数据
  try {
    const invalidExporter = new PPTXExporter(null);
    await invalidExporter.toBuffer();
  } catch (error) {
    console.log('✅ 无效数据处理正常:', error.message);
  }

  // 测试不支持的格式
  try {
    const exporter = new PPTXExporter(basicTestData);
    await exporter.export({
      outputType: 'unsupported',
      compression: false,
    });
  } catch (error) {
    console.log('✅ 不支持格式处理正常:', error.message);
  }
}

async function runComprehensiveTests() {
  console.log('🚀 开始综合测试 PPTX Exporter...\n');

  try {
    // 环境检测
    const basicExporter = await testEnvironmentDetection();

    // 基础测试
    await testBasicExport(basicExporter, 'basic-test', basicTestData);
    await testAllExportFormats(basicExporter, 'basic-test');
    await testFileExport(basicExporter, 'basic-test');

    // 空演示文稿测试
    console.log('\n📄 测试空演示文稿...');
    const emptyExporter = new PPTXExporter(emptyTestData, {
      onProgress: createProgressTracker('空演示文稿'),
    });
    await testBasicExport(emptyExporter, 'empty-test', emptyTestData);
    await testAllExportFormats(emptyExporter, 'empty-test');
    await testFileExport(emptyExporter, 'empty-test');

    // 模板数据测试
    console.log('\n📋 测试模板数据...');
    const templateData = await loadTemplateData();
    if (templateData) {
      const templateExporter = new PPTXExporter(templateData, {
        onProgress: createProgressTracker('模板数据'),
      });
      await testBasicExport(templateExporter, 'template-test', templateData);
      await testAllExportFormats(templateExporter, 'template-test');
      await testFileExport(templateExporter, 'template-test');
    }

    // 错误处理测试
    await testErrorHandling();

    console.log('\n🎉 所有测试完成！');
    console.log('📁 输出文件保存在 ./test/output/ 目录中');
    console.log('\n📊 测试总结:');
    console.log('- ✅ 环境检测功能正常');
    console.log('- ✅ 基础导出功能正常');
    console.log('- ✅ 空演示文稿处理正常');
    console.log('- ✅ 模板数据处理正常');
    console.log('- ✅ 所有导出格式支持正常');
    console.log('- ✅ 错误处理机制正常');
    console.log('- ✅ 文件导出功能正常');
  } catch (error) {
    console.error('❌ 测试过程中发生错误:', error.message);
    console.error('错误堆栈:', error.stack);
    process.exit(1);
  }
}

// 运行测试
runComprehensiveTests();
